/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package biofilter.filters;

import biofilter.exceptions.InvalidRecordException;
import biofilter.records.HistogramRecord;
import biofilter.util.SequencePosition;
import biofilter.records.Record;
import biofilter.sources.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author qvh
 */
public class HistogramFilterTest {

    public HistogramFilterTest() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    SequencePosition s1 = null;
    SequencePosition s2 = null;
    SequencePosition s3 = null;
    SequencePosition s4 = null;
    SequencePosition s5 = null;
    SequencePosition s6 = null;
    SequencePosition s7 = null;
    SequencePosition s8 = null;
    SequencePosition s9 = null;
    SequencePosition s10 = null;
    SequencePosition s11 = null;

    private void init(){
        //HWI-EAS127_3_4_1_774_879	-	ctg93	4	AAN	III	1	38:G>N
        s1 = new SequencePosition(7,5,'-');
        s1.setSubjectID("ctg93");
        s1.setWeight(2.0/3);
        //HWI-EAS127_3_4_1_774_879	-	ctg94	3	AAN	III	1	38:G>N
        s2 = new SequencePosition(6,4,'-');
        s2.setSubjectID("ctg94");
        s2.setWeight(2.0/3);
        //HWI-EAS127_3_4_1_774_879	-	ctg95	6	AAT	III	0	38:G>N
        s3 = new SequencePosition(9,7,'-');
        s3.setSubjectID("ctg95");
        s3.setWeight(2.0/3);
        //HWI-EAS127_3_4_1_774_879	+	ctg95	1	GTT	III	0	38:C>N
        s4 = new SequencePosition(2,4,'+');
        s4.setSubjectID("ctg95");
        s4.setWeight(2.0/3);
        //HWI-EAS127_3_4_1_774_879	+	ctg95	2	NAG	III	1	38:C>N
        s5 = new SequencePosition(3,5,'+');
        s5.setSubjectID("ctg95");
        s5.setWeight(2.0/3);
        //HWI-EAS127_3_4_1_774_879	+	ctg95	3	GAG	III	0	38:C>N
        s6 = new SequencePosition(4,6,'+');
        s6.setSubjectID("ctg95");
        s6.setWeight(2.0/3);
        //HWI-EAS127_3_4_1_36_5261	-	ctg95	7	TCA	III	0	38:G>N
        s7 = new SequencePosition(10,8,'-');
        s7.setSubjectID("ctg95");
        s7.setWeight(2.0/3);
        //HWI-EAS127_3_4_1_36_5261	+	ctg94	1	TCA	III	0	38:G>N
        s8 = new SequencePosition(2,4,'+');
        s8.setSubjectID("ctg94");
        s8.setWeight(2.0/3);
        //HWI-EAS127_3_4_1_36_5261	-	ctg93	4	TCA	III	0	38:G>N
        s9 = new SequencePosition(7,5,'-');
        s9.setSubjectID("ctg93");
        s9.setWeight(2.0/3);
        //HWI-EAS127_3_4_1_36_5261	+	ctg95	3	TTT	III	0	38:C>N
        s10 = new SequencePosition(4,6,'+');
        s10.setSubjectID("ctg95");
        s10.setWeight(2.0/3);
        //HWI-EAS127_3_4_1_36_5265	+	ctg95	3	TTT	III	0	38:C>N
        s11 = new SequencePosition(4,6,'+');
        s11.setSubjectID("ctg95");
        s11.setWeight(2.0/3);
    }
    /**
     * Test of transformRecord method, of class HistogramFilter.
     * In this test, the values of each sequence position don't matter, we will consider them as if they
     * where all == 1.
     */
    @Test
    public void testTransformRecord() throws Exception {
        init();
        s1.setWeight(1.0);
        s2.setWeight(1.0);
        s3.setWeight(1.0);
        s4.setWeight(1.0);
        s5.setWeight(1.0);
        s6.setWeight(1.0);
        s7.setWeight(1.0);
        s8.setWeight(1.0);
        s9.setWeight(1.0);
        s10.setWeight(1.0);
        s11.setWeight(1.0);

        HistogramRecord hr1 = new HistogramRecord();
        hr1.setTarget("ctg93");
        HistogramRecord hr2 = new HistogramRecord();
        hr2.setTarget("ctg94");
        HistogramRecord hr3 = new HistogramRecord();
        hr3.setTarget("ctg95");
        hr1.map(s1);
        hr2.map(s2);
        hr3.map(s3);
        hr3.map(s4);
        hr3.map(s5);
        hr3.map(s6);
        hr3.map(s7);
        hr2.map(s8);
        hr1.map(s9);
        hr3.map(s10);
        hr3.map(s11);

        //hr1
        //0.0 0.0 -1
        //0.0 0.0 -2
        //0.0 0.0 -3
        //0.0 0.0 -4
        //0.0 2.0 -5
        //0.0 2.0 -6
        //0.0 2.0 -7

        //hr2
        //0.0 0.0
        //1.0 0.0
        //1.0 0.0
        //1.0 1.0
        //0.0 1.0
        //0.0 1.0
        //0.0 0.0

        //hr3
        //0.0 0.0
        //1.0 0.0
        //2.0 0.0
        //5.0 0.0
        //4.0 0.0
        //3.0 0.0
        //0.0 1.0
        //0.0 2.0
        //0.0 2.0
        //0.0 1.0

        System.out.println("transformRecord");
        BowTieRecordsFile btrf = new BowTieRecordsFile("./test/testdata/simple.bowtie");
        HistogramFilter instance = new HistogramFilter(btrf);
        assertEquals(instance.getUnique(), false);
        //first just test to make sure raw scores can be added, this will count 1 regardless of the real score
        HistogramRecord result1 = (HistogramRecord) instance.getRecord();
        HistogramRecord result2 = (HistogramRecord) instance.getRecord();
        HistogramRecord result3 = (HistogramRecord) instance.getRecord();
        assertEquals(hr1.get(), result1.get());
        assertEquals(hr2.get(), result2.get());
        assertEquals(hr3.get(), result3.get());

    }


     /**
     * Test of transformRecord method, of class HistogramFilter
      * given that the filter must only place reads that map uniquely
      * e.g. a read can not map to two or more locations in the genome/plasmid
     */
    @Test
    public void testTransformRecordUnique() throws Exception {
        init();
        s11.setWeight(1.0);
        
        HistogramRecord hr1 = new HistogramRecord();
        hr1.setTarget("ctg93");
        HistogramRecord hr2 = new HistogramRecord();
        hr2.setTarget("ctg94");
        HistogramRecord hr3 = new HistogramRecord();
        hr3.setTarget("ctg95");
        hr3.map(s11);

        System.out.println("transformRecordUnique");
        BowTieRecordsFile btrf = new BowTieRecordsFile("./test/testdata/simple.bowtie");
        HistogramFilter instance = new HistogramFilter(btrf);
        instance.unique();
        HistogramRecord result1 = (HistogramRecord) instance.getRecord();
        HistogramRecord result2 = (HistogramRecord) instance.getRecord();
        HistogramRecord result3 = (HistogramRecord) instance.getRecord();
        assertEquals(hr1.get(), result1.get());
        assertEquals(hr2.get(), result2.get());
        assertEquals(hr3.get(), result3.get());
    }

    @Test
    public void testTransformRecordRawScore(){
        try {
            init();
            s1.setWeight(0.0);
            s2.setWeight(0.0);
            s3.setWeight(3.0);
            s4.setWeight(3.0);
            s5.setWeight(0.0);
            s6.setWeight(3.0);
            s7.setWeight(3.0);
            s8.setWeight(3.0);
            s9.setWeight(3.0);
            s10.setWeight(3.0);
            s11.setWeight(3.0);
            HistogramRecord hr1 = new HistogramRecord();
            hr1.setTarget("ctg93");
            HistogramRecord hr2 = new HistogramRecord();
            hr2.setTarget("ctg94");
            HistogramRecord hr3 = new HistogramRecord();
            hr3.setTarget("ctg95");
            hr1.map(s1);
            hr2.map(s2);
            hr3.map(s3);
            hr3.map(s4);
            hr3.map(s5);
            hr3.map(s6);
            hr3.map(s7);
            hr2.map(s8);
            hr1.map(s9);
            hr3.map(s10);
            hr3.map(s11);

            System.out.println("transformRecordRawScore");
            BowTieRecordsFile btrf = new BowTieRecordsFile("./test/testdata/simple.bowtie");
            HistogramFilter instance = new HistogramFilter(btrf);
            /**
             * the following line asks for the RAW score to be the weight
             */
            instance.setRawScore(true);
            HistogramRecord result1 = (HistogramRecord) instance.getRecord();
            HistogramRecord result2 = (HistogramRecord) instance.getRecord();
            HistogramRecord result3 = (HistogramRecord) instance.getRecord();
            assertEquals(hr1.get(), result1.get());
            assertEquals(hr2.get(), result2.get());
            assertEquals(hr3.get(), result3.get());

        } catch (InvalidRecordException ex) {
            Logger.getLogger(HistogramFilterTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Test
    public void testTransformRecordNormalizePerRead(){
        try {
            init();
            s1.setWeight(0.0);
            s2.setWeight(0.0);
            s3.setWeight(1.0);
            s4.setWeight(1.0);
            s5.setWeight(0.0);
            s6.setWeight(1.0);
            s7.setWeight(1.0);
            s8.setWeight(1.0);
            s9.setWeight(1.0);
            s10.setWeight(1.0);
            s11.setWeight(1.0);
            HistogramRecord hr1 = new HistogramRecord();
            hr1.setTarget("ctg93");
            HistogramRecord hr2 = new HistogramRecord();
            hr2.setTarget("ctg94");
            HistogramRecord hr3 = new HistogramRecord();
            hr3.setTarget("ctg95");
            hr1.map(s1);
            hr2.map(s2);
            hr3.map(s3);
            hr3.map(s4);
            hr3.map(s5);
            hr3.map(s6);
            hr3.map(s7);
            hr2.map(s8);
            hr1.map(s9);
            hr3.map(s10);
            hr3.map(s11);

            System.out.println("transformRecordNormalizePerRead");
            BowTieRecordsFile btrf = new BowTieRecordsFile("./test/testdata/simple.bowtie");
            HistogramFilter instance = new HistogramFilter(btrf);
            /**
             * the following line asks for the RAW score / read length added to the weight
             */
            instance.setNormalizePerRead(true);
            HistogramRecord result1 = (HistogramRecord) instance.getRecord();
            HistogramRecord result2 = (HistogramRecord) instance.getRecord();
            HistogramRecord result3 = (HistogramRecord) instance.getRecord();
            assertEquals(hr1.get(), result1.get());
            assertEquals(hr2.get(), result2.get());
            assertEquals(hr3.get(), result3.get());

        } catch (InvalidRecordException ex) {
            Logger.getLogger(HistogramFilterTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}